package cn.iocoder.yudao.module.system.service.tradinghours;

import cn.iocoder.yudao.framework.common.enums.TradingHoursTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.controller.admin.tradinghours.vo.SystemTradingHoursPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.tradinghours.vo.SystemTradingHoursRespVO;
import cn.iocoder.yudao.module.system.controller.admin.tradinghours.vo.SystemTradingHoursSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.tradinghours.SystemTradingHoursDO;
import cn.iocoder.yudao.module.system.dal.mysql.tradinghours.SystemTradingHoursMapper;
import jakarta.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TRADING_HOURS_NOT_EXISTS;

/**
 * 营业时间 Service 实现类
 *
 * @author admin
 */
@Service
@Validated
public class SystemTradingHoursServiceImpl implements SystemTradingHoursService {

    @Resource
    private SystemTradingHoursMapper tradingHoursMapper;

    @Override
    @CacheEvict(cacheNames = "SYSTEM_TRADING_HOURS", key = "'TYPE:' + #createReqVO.getType() + 'MODULE:'+ #createReqVO.getModule()")
    public Long createTradingHours(SystemTradingHoursSaveReqVO createReqVO) {
        // 检查是否需要更新而不是创建
        if (createReqVO.getType() != null && TradingHoursTypeEnum.SPECIAL.getType().equals(createReqVO.getType()) && createReqVO.getTradingDate() != null) {
            // 特殊日期模式 - 根据类型和特殊日期查询是否存在
            SystemTradingHoursDO existingRecord = tradingHoursMapper.selectByTypeAndTradingDate(
                    createReqVO.getType(), createReqVO.getModule(), createReqVO.getTradingDate());
            
            if (existingRecord != null) {
                // 存在记录，执行更新操作
                createReqVO.setId(existingRecord.getId());
                updateTradingHours(createReqVO);
                return existingRecord.getId();
            }
        }
        
        // 不存在记录或非特殊日期模式，执行插入操作
        SystemTradingHoursDO tradingHours = BeanUtils.toBean(createReqVO, SystemTradingHoursDO.class);
        tradingHoursMapper.insert(tradingHours);
        // 返回
        return tradingHours.getId();
    }

    @Override
    @CacheEvict(cacheNames = "SYSTEM_TRADING_HOURS", key = "'TYPE:1' + 'MODULE:'+ #updateReqVO.getModule()")
    public void updateTradingHours(SystemTradingHoursSaveReqVO updateReqVO) {
        // 校验存在
        validateTradingHoursExists(updateReqVO.getId());
        // 更新
        SystemTradingHoursDO updateObj = BeanUtils.toBean(updateReqVO, SystemTradingHoursDO.class);
        tradingHoursMapper.updateById(updateObj);
    }

    @Override
    @CacheEvict(cacheNames = "SYSTEM_TRADING_HOURS", allEntries = true)
    public void deleteTradingHours(Long id) {
        // 校验存在
        validateTradingHoursExists(id);
        // 删除
        tradingHoursMapper.deleteById(id);
    }

    private void validateTradingHoursExists(Long id) {
        if (tradingHoursMapper.selectById(id) == null) {
            throw exception(TRADING_HOURS_NOT_EXISTS);
        }
    }

    @Override
    public SystemTradingHoursDO getTradingHours(Long id) {
        return tradingHoursMapper.selectById(id);
    }

    @Override
    public PageResult<SystemTradingHoursDO> getTradingHoursPage(SystemTradingHoursPageReqVO pageReqVO) {
        return tradingHoursMapper.selectPage(pageReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "SYSTEM_TRADING_HOURS", key = "'TYPE:0' + 'MODULE:'+ #saveReqVOS.get(0).getModule()")
    public List<SystemTradingHoursRespVO> saveWeeklyTradingHours(List<SystemTradingHoursSaveReqVO> saveReqVOS) {
        if (saveReqVOS == null || saveReqVOS.isEmpty()) {
            return Collections.emptyList();
        }
        
        List<SystemTradingHoursRespVO> result = new ArrayList<>(saveReqVOS.size());
        
        for (SystemTradingHoursSaveReqVO reqVO : saveReqVOS) {
            // 根据类型和星期几查询是否存在记录
            SystemTradingHoursDO existingRecord = tradingHoursMapper.selectByTypeAndDayOfWeek(reqVO.getType(), reqVO.getModule(), reqVO.getDayOfWeek());
            
            // 存在则更新，不存在则创建
            if (existingRecord != null) {
                reqVO.setId(existingRecord.getId()); // 设置ID用于更新
                SystemTradingHoursDO updateObj = BeanUtils.toBean(reqVO, SystemTradingHoursDO.class);
                tradingHoursMapper.updateById(updateObj);
                result.add(BeanUtils.toBean(getTradingHours(existingRecord.getId()), SystemTradingHoursRespVO.class));
            } else {
                Long id = createTradingHours(reqVO);
                result.add(BeanUtils.toBean(getTradingHours(id), SystemTradingHoursRespVO.class));
            }
        }
        
        return result;
    }

    @Override
    @Cacheable(cacheNames = "SYSTEM_TRADING_HOURS", key = "'TYPE:'+ #type + 'MODULE:' + #module", unless = "#result == null")
    public List<SystemTradingHoursRespVO> getTradingHoursList(Integer type, Integer module, LocalDate startDate, LocalDate endDate) {
        List<SystemTradingHoursDO> tradingHoursList;
        
        if (TradingHoursTypeEnum.WEEKDAY.getType().equals(type)) {
            // 查询每周营业时间
            tradingHoursList = tradingHoursMapper.selectListByType(type, module);
        } else if (TradingHoursTypeEnum.SPECIAL.getType().equals(type)) {
            // 查询特殊日期营业时间
            tradingHoursList = tradingHoursMapper.selectListByTypeAndDateRange(type, module, startDate, endDate);
        } else {
            // 不支持的类型
            return Collections.emptyList();
        }
        
        // 将DO转换为VO
        return BeanUtils.toBean(tradingHoursList, SystemTradingHoursRespVO.class);
    }

}